﻿using CommonModule;
using HalconDotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace VisionModule
{
    public class ImageProcess
    {
        private Dictionary<string, HTuple> windowsHandleDic = new Dictionary<string, HTuple>();
        private static readonly ImageProcess instance = new ImageProcess();

        public static ImageProcess Instance => instance;
        private ImageProcess() { }
        /// <summary>
        /// 打开窗口
        /// </summary>
        /// <param name="width">窗口宽</param>
        /// <param name="height">窗口高</param>
        /// <param name="handle">窗口容器句柄</param>
        /// <param name="windowName">窗口名称</param>
        public void OpenWindow(HTuple width, HTuple height, HTuple handle, string windowName)
        {
            HOperatorSet.OpenWindow(0, 0, width, height, handle, "visible", "", out HTuple tempHandle);
            windowsHandleDic.Add(windowName, tempHandle);
            HDevWindowStack.Push(tempHandle);
        }
        /// <summary>
        /// 显示图像
        /// </summary>
        /// <param name="image">图像</param>
        /// <param name="windowName">窗口名称</param>
        public void ShowImage(HObject image, string windowName)
        {
            HTuple hv_Width, hv_Height;
            if (image != null)
            {
                HDevWindowStack.SetActive(windowsHandleDic[windowName]);
                HOperatorSet.GetImageSize(image, out hv_Width, out hv_Height);
                if (HDevWindowStack.IsOpen())
                {
                    HOperatorSet.SetPart(HDevWindowStack.GetActive(), 0, 0, hv_Height, hv_Width);
                    HOperatorSet.DispObj(image, HDevWindowStack.GetActive());
                }
            }
        }
        public void ShowObject(HObject obj, string windowName, string fill = "margin")
        {
            if (obj != null)
            {
                if (HDevWindowStack.IsOpen())
                {
                    HDevWindowStack.SetActive(windowsHandleDic[windowName]);//设置为激活窗口
                    HOperatorSet.SetLineWidth(HDevWindowStack.GetActive(), 3);
                    HOperatorSet.SetDraw(HDevWindowStack.GetActive(), fill);
                    HOperatorSet.SetColored(HDevWindowStack.GetActive(), new HTuple(12));
                    HOperatorSet.DispObj(obj, HDevWindowStack.GetActive());
                }
            }
        }
        public HObject CreateModel(HObject image, ImageParameters parameters, CreateModelParamerters modelParamerters, out HTuple row, out HTuple column)
        {
            HImage Image = new HImage(image);
            HImage tempImage = new HImage();
            HRegion tempRegion = new HRegion();
            HShapeModel shapeModel = new HShapeModel();
            HXLDCont tempXLD = new HXLDCont();
            HObject tempObject = new HObject();
            tempObject.GenEmptyObj();
            //ScaleImage参数说明
            double mult = 255 / (parameters.ScaleMax - parameters.ScaleMin);
            double add = -(mult * parameters.ScaleMin);
            //预处理
            tempImage = Image.ScaleImage(mult, add);
            tempRegion = tempImage.Threshold(parameters.ThresholdMin, parameters.ThresholdMax);
            tempRegion = tempRegion.Connection();
            tempRegion = tempRegion.SelectShape("area", "and", parameters.AreaMin, parameters.AreaMax);
            tempRegion = tempRegion.ShapeTrans("outer_circle");
            tempRegion = tempRegion.Boundary("inner");
            tempRegion = tempRegion.DilationCircle(10.5);
            //创建模板,
            shapeModel.CreateShapeModel(tempImage.ReduceDomain(tempRegion),
                "auto", modelParamerters.AngleMin, modelParamerters.AngleMax, "auto", "auto",
                modelParamerters.Polarity.ToString(), modelParamerters.Contrast, modelParamerters.ContrastMin);
            tempXLD = shapeModel.GetShapeModelContours(1);
            //获得轮廓参数，方便显示
            shapeModel.FindShapeModel(tempImage, modelParamerters.AngleMin, modelParamerters.AngleMax,
                0.5, 1, 0.5, "least_squares", 0, 0.7, out row, out column, out HTuple angel, out HTuple socre);
            if (row.TupleLength() > 0)
            {
                //轮廓仿射变换
                HHomMat2D homMat2D = new HHomMat2D();
                homMat2D.VectorAngleToRigid(0, 0, 0, row, column, 0);
                HXLDCont xld = homMat2D.AffineTransContourXld(tempXLD);
                HOperatorSet.ConcatObj(xld, tempObject, out tempObject);
                HXLDCont cross = new HXLDCont();//添加点
                cross.GenCrossContourXld(row, column, 15, 0);
                HOperatorSet.ConcatObj(tempObject, cross, out tempObject);
            }
            return tempObject;
        }

        public void AutoCalibration()
        {

        }

    }
}
